package com.yjz.jvm.juc.ExecutorService;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.concurrent.*;

/**
 * @author :yuanJinZhong
 * @description: juc  future相关学习  和 线程池   ExecutorService 学习
 * @date :2018/7/12-10:41
 */
@Slf4j
public class jdk_ExecutorService_future {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        /**
         * 1:创建线程池
         */
        ExecutorService executor = Executors.newCachedThreadPool();
        /**
         * 2:创建callable 任务 （和 Runnable 一样 都叫任务，Thread 才叫线程）
         *   Runnable不会返回结果，也不能抛出一个检查类型的异常,callable能返回结果，也能抛出一个检查型异常
         *   检查型异常：编译器会自动检查的异常，若编译器认为可能会抛异常，编译器会强制开发中try catch  或者throws
         *   非检查型异常的区别：编译器认为代码没问题，然后代码运行过程中抛出的异常叫 非检查异常
         */
        Task task = new Task("电脑计算器");

        /**
         * 3：将任务提交到线程池（交由线程处理），并返回一个结果（Future 称之为结果）
         */
        Future<Integer> result = executor.submit(task);
        /**
         * 4：阻住新的任务（callable）提交，若后续再提交 会报错！
         */
        //executor.shutdown();

        Task task2 = new Task("手机计算器");

        executor.submit(task2);

        /**
         * 5:result.get() 从Futhre 实现类的对象中获取这次提交任务的结果，若调用此方法，后续代码会阻塞
         */
        log.info("taks运行结果" + result.get());

        log.info("任务是否结束：" + result.isDone());


        Task task3 = new Task("计算器");
        executor.submit(task3);

        executor.shutdown();

        log.info("主线程执行结束");

    }

    @Getter
    @Setter
    @AllArgsConstructor
    public static class Task implements Callable<Integer> {
        private String name;

        @Override
        public Integer call() throws Exception {
            log.info(name + "在进行计算");
            Thread.sleep(3000);
            int sum = 0;
            for (int i = 0; i < 5; i++) {
                sum += i;
            }
            return sum;
        }
    }


    @Test
    public void 测试CallerRunsPolicy会不会导致oom() {

      ThreadPoolExecutor threadPoolExecutor=new ThreadPoolExecutor(1,1,10L,TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>(10), new ThreadPoolExecutor.CallerRunsPolicy());
    }


}
